#pragma once
#ifndef __AGENT_HEADER__
#define __AGENT_HEADER__

#include "stdafx.h"
#include "Common.hpp"
#include "SteeringBehaviors.hpp"
#include "Smoother.hpp"


//////////////////////////////////////////////////////////////////////////

enum AgentType
{
	AGENT_ANY,
	AGENT_FISH,
	AGENT_PREDATOR,
	AGENT_DIVER
};

class Agent
{
protected:
	vec3 _position;
	vec3 _velocity;
	vec3 _heading;

	bool _tagged;

	SteeringBehaviors _steering;

	mat3 _rotMat;

	Smoother<vec3> _headingSmoother;
	vec3 _headingSmoothed;

	Ogre::SceneNode* _sceneNode;
	Ogre::SceneNode* _axesNode;

	vec3 forwardComponent(const vec3& v) const;
	vec3 sideComponent(const vec3& v) const;

	virtual vec3 calcSteeringForce(float dt) = 0;

public:
	Agent(const vec3& pos = vec3::ZERO);

	virtual AgentType getType() const = 0;

	vec3 getPosition() const { return _position; }
	vec3 getVelocity() const { return _velocity; }
	vec3 getHeading() const { return _heading; }
	virtual float getMass() const = 0;
	virtual float getRadius() const = 0;
	virtual float getMaxVelocity() const = 0;
	virtual float getTurnRate() const = 0;

	void setPosition(const vec3& pos) { _position = pos; }

	virtual void update(float dt);
	virtual void draw() const = 0;

	bool isTagged() const { return _tagged; }
	void tag() { _tagged = true; }
	void untag() { _tagged = false; }
};

//////////////////////////////////////////////////////////////////////////

#endif // #ifndef __AGENT_HEADER__